import React, { useCallback, useContext, useEffect } from 'react';
import { Modal, Form, Select, Tooltip, Button, Icon, Row, Col, message } from 'antd';
import classNames from 'classnames';
import { useDynamicList } from '@/hooks';
import { trim, omit } from 'lodash';

import If from '@/components/If';

import { BaseSettingContext } from '@/pages/SalaryManage/constant/BaseSettingContext';
import { NumberSettingInput, PercentSettingInput } from '@/pages/SalaryManage/components/NumberSettingInput';
import { cpfFormulaTypeEnum, cpfFormulaType } from '@/pages/SalaryManage/enum';
import salaryStyle from '@/pages/SalaryManage/salaryManage.less';

import util from './util';
import cpfSettingStyle from './index.less';

const FormulaTypeSelect = React.forwardRef(({ value, onChange, className, ...otherProps }, ref) => (
    <Select
        value={value}
        onChange={onChange}
        {...otherProps}
        className={classNames(cpfSettingStyle.formulaTypeSelect, className)}
        ref={ref}
    >
        {cpfFormulaTypeEnum.list().map(type => (
            <Select.Option key={type.value} value={type.value}>
                {type.text}
            </Select.Option>
        ))}
    </Select>
));

const ShareInput = ({ index, dataSource, formulaType, showMax, onUpdate, validateField, style }) => {
    const errorFieldMap = dataSource?.vvValidateInfo?.errorField || {};

    const shareRateRender = (
        <PercentSettingInput
            value={dataSource.shareRate}
            onChange={value => {
                onUpdate('shareRate', value, index, dataSource);
            }}
            onBlur={util.delayExecute(() => validateField(['shareRate'], index, dataSource))}
            suffix="%"
            className={classNames(cpfSettingStyle.input, {
                [cpfSettingStyle.error]: errorFieldMap?.shareRate
            })}
        />
    );
    let content;
    switch (formulaType) {
        case cpfFormulaType.NIL:
            content = 'Nil';
            break;

        case cpfFormulaType.TW:
            content = (
                <React.Fragment>
                    {shareRateRender} <span>(TW)</span>
                </React.Fragment>
            );
            break;

        case cpfFormulaType.AW:
            content = (
                <>
                    {shareRateRender}
                    <span>(AW)</span>
                </>
            );
            break;

        case cpfFormulaType.OW:
            content = (
                <>
                    {shareRateRender}
                    <span>(OW)</span>
                </>
            );
            break;

        case cpfFormulaType.TWB:
            content = (
                <>
                    {shareRateRender}
                    <span>(TW - </span>
                    <NumberSettingInput
                        prefix="$"
                        value={dataSource.shareAmt}
                        onChange={value => {
                            onUpdate('shareAmt', value, index, dataSource);
                        }}
                        onBlur={util.delayExecute(() => validateField(['shareAmt'], index, dataSource))}
                        className={classNames(cpfSettingStyle.input, {
                            [cpfSettingStyle.error]: errorFieldMap?.shareAmt
                        })}
                        align="left"
                        style={{ width: 90 }}
                    />
                    <span>)</span>
                </>
            );
            break;

        default:
            content = <span className={cpfSettingStyle.placeholder}>请选择公式</span>;
    }

    const maxContent = (
        <span style={{ display: showMax ? 'inline-block' : 'none' }}>
            <span>上限：</span>
            <NumberSettingInput
                prefix="$"
                value={dataSource.maxAmt}
                onChange={value => {
                    onUpdate('maxAmt', value, index, dataSource);
                }}
                align="left"
                className={classNames(cpfSettingStyle.input, {
                    [cpfSettingStyle.error]: errorFieldMap?.maxAmt
                })}
                style={{ width: 70 }}
            />
        </span>
    );

    return (
        <div className={cpfSettingStyle.shareInput} style={{ ...style }}>
            {content}
            {maxContent}
        </div>
    );
};
ShareInput.defaultProps = {
    style: {}
};

const ShareRowValidateResult = ({ validateInfo }) => <div className={cpfSettingStyle.validateBox}>{validateInfo}</div>;

const ShareItem = ({ index, dataSource, length, typeChange, onToggle, onAdd, onDelete, onUpdate, validateField }) => {
    const errorFieldMap = dataSource?.vvValidateInfo?.errorField || {};
    return (
        <Row className={cpfSettingStyle.shareRow}>
            <Col span={20}>
                <Row className={classNames(cpfSettingStyle.shareItem, cpfSettingStyle.shareInputItem)}>
                    <FormulaTypeSelect
                        onChange={type => typeChange(type, index, dataSource)}
                        value={dataSource.formulaType}
                        placeholder="公式"
                        className={classNames({ [cpfSettingStyle.error]: errorFieldMap?.formulaType })}
                    />
                    <ShareInput
                        index={index}
                        dataSource={dataSource}
                        formulaType={dataSource.formulaType}
                        showMax={util.needShowMax(dataSource)}
                        onUpdate={onUpdate}
                        validateField={validateField}
                    />
                </Row>
                <Row>
                    <ShareRowValidateResult validateInfo={dataSource?.vvValidateInfo?.message} />
                </Row>
            </Col>
            <Col span={4} className={classNames(cpfSettingStyle.shareItem, cpfSettingStyle.shareOperateItem)}>
                <If condition={cpfFormulaType.NIL !== dataSource.formulaType}>
                    <Tooltip title={util.needShowMax(dataSource) ? '取消设置上限' : '设置上限'}>
                        <Button
                            className={classNames(salaryStyle.operateIcon)}
                            onClick={() => onToggle(index, dataSource)}
                        >
                            <Icon type="vertical-align-top" />
                        </Button>
                    </Tooltip>
                </If>
                <Tooltip title="添加">
                    <Button className={classNames(salaryStyle.operateIcon)} onClick={() => onAdd(index, dataSource)}>
                        <Icon type="plus-circle" />
                    </Button>
                </Tooltip>
                {/* 行数为1时不显示删除按钮 */}
                <If condition={length > 1}>
                    <Tooltip title="删除">
                        <Button
                            className={classNames(salaryStyle.operateIcon)}
                            onClick={() => onDelete(index, dataSource)}
                        >
                            <Icon type="minus-circle" />
                        </Button>
                    </Tooltip>
                </If>
            </Col>
        </Row>
    );
};

/**
 * 添加校验信息
 * @param {Array | Object} rows 要校验的行
 * @param {?Array} validateFields 要校验的字段
 * @returns {(*&{validateInfo: {errorField, message}})|*}
 */
const addValidateInfo = (rows, validateFields) =>
    util.mapRows(rows, row => ({ vvValidateInfo: util.validateFormulaRow(row, validateFields) }));

/** 添加前台用到的辅助字段 */
const addAssistInfo = rows => util.mapRows(rows, row => ({ vvShowMax: util.needShowMax(row) }));

/**
 * 公积金缴交比例模态框
 */
const CPFContributionsModal = ({ title, visible, model, onCancel, onOk }) => {
    const {
        baseSetting: { scale = 2 }
    } = useContext(BaseSettingContext);
    const { list: dataSource, resetList: resetDataSource, getKey, replace, remove, insert } = useDynamicList([]);

    const handleTypeChange = (type, index, record) => {
        let newRecord = {};
        if (cpfFormulaType.NIL === type) {
            newRecord = { shareAmt: null, shareRate: null, maxAmt: null };
        } else if (cpfFormulaType.TWB !== type) {
            newRecord = { shareAmt: null };
        }
        replace(index, { ...record, formulaType: type, ...newRecord });
    };

    const handleToggle = (index, record) => {
        const { vvShowMax } = record;
        const newVvShowMax = !vvShowMax;
        const newRecord = {
            ...record,
            vvShowMax: newVvShowMax,
            maxAmt: newVvShowMax ? record.maxAmt : null
        };
        replace(index, newRecord);
    };

    const handleAdd = index => {
        if (dataSource.length >= 5) {
            message.error('最多添加5条数据！');
            return;
        }
        insert(index + 1, addAssistInfo({}));
    };

    const handleDelete = index => {
        remove(index);
    };

    const handleOk = () => {
        const newDataSource = addValidateInfo(dataSource);
        resetDataSource(newDataSource);

        // 如果校验不通过
        if (newDataSource.find(data => trim(data.vvValidateInfo.message))) {
            return;
        }
        onOk(newDataSource.map(item => omit(item, ['vvValidateInfo', 'vvShowMax'])));
    };

    const handleRowUpdate = (field, fieldValue, index, record) => {
        const newRecord = { ...record, [field]: fieldValue };
        replace(index, newRecord);
    };

    /** 根据给定字段校验 */
    const validateField = useCallback(
        (fields, index) => {
            const record = dataSource[index];
            // 取出原有校验不通过的字段
            const errorFields = Object.keys(record?.vvValidateInfo?.errorField || {});
            const validateFields = [...errorFields, ...fields];
            const newRecord = { ...addValidateInfo(dataSource[index], validateFields) };

            replace(index, newRecord);
        },
        [dataSource, replace]
    );

    useEffect(() => {
        if (model) {
            resetDataSource(addAssistInfo(Array.isArray(model) ? model : [model]));
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [model]);

    return (
        <Modal title={title} visible={visible} onCancel={onCancel} onOk={handleOk} width={740}>
            <div className={cpfSettingStyle.cpfContributionsModal}>
                <Form className={cpfSettingStyle.shareBox} layout="inline">
                    {dataSource.map((data, index, array) => (
                        <ShareItem
                            key={getKey(index)}
                            index={index}
                            length={array.length}
                            dataSource={data}
                            typeChange={handleTypeChange}
                            onToggle={handleToggle}
                            onAdd={handleAdd}
                            onDelete={handleDelete}
                            onUpdate={handleRowUpdate}
                            validateField={validateField}
                        />
                    ))}
                    <Row>
                        <Col span={19}>
                            <div className={cpfSettingStyle.preview}>
                                <pre>{util.getFormulaDescription(dataSource, scale)}</pre>
                            </div>
                        </Col>
                    </Row>
                </Form>
            </div>
        </Modal>
    );
};
CPFContributionsModal.defaultProps = {
    title: '缴交比例',
    model: [{}],
    onCancel: () => {},
    onOk: () => {}
};

export default CPFContributionsModal;
